package com.ruoyi.system.test;

import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.system.domain.SysNotices;
import com.ruoyi.system.service.IAttendanceRecordService;
import com.ruoyi.system.service.ISysDeptService;
import com.ruoyi.system.service.ISysNoticesService;
import com.ruoyi.system.service.ISysUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Component
public class AttendanceCheckTask {

    @Autowired
    private IAttendanceRecordService attendanceRecordService;

    @Autowired
    private ISysNoticesService sysNoticesService;

    @Autowired
    private ISysUserService sysUserService;

    @Autowired
    private ISysDeptService sysDeptService;

    private static final Logger logger = LoggerFactory.getLogger(AttendanceCheckTask.class);

    @Scheduled(cron = "0 20 9 * * ? ") // 保持原有的cron表达式
    public void checkMonthlyAttendance() {
        logger.info("【定时任务】开始生成月度全勤公告...");

        LocalDate lastMonthDate = LocalDate.now().minusMonths(1);
        String lastMonth = lastMonthDate.format(DateTimeFormatter.ofPattern("yyyy年MM月"));

        List<Map<String, Object>> userList = attendanceRecordService.selectUsersWithNormalDaysLastMonth();
        if (userList.isEmpty()) {
            logger.info("上月无符合条件的考勤记录，跳过公告生成");
            return;
        }

        // 收集用户考勤数据并转换为对象列表
        List<UserAttendance> attendanceList = userList.stream()
                .map(user -> {
                    Long userId = (Long) user.get("userId");
                    Integer normalDays = ((Long) user.get("normalDays")).intValue();
                    SysUser sysUser = sysUserService.selectUserById(userId);
                    if (sysUser == null) {
                        logger.warn("用户ID {} 不存在，跳过该用户", userId);
                        return null;
                    }
                    String deptName = getDeptName(sysUser.getDeptId());
                    return new UserAttendance(deptName, sysUser.getNickName(), normalDays);
                })
                .filter(Objects::nonNull)
                .collect(Collectors.toList());

        if (attendanceList.isEmpty()) {
            logger.info("无有效用户数据，跳过公告生成");
            return;
        }

        // 构建考勤统计表
        String tableContent = buildAttendanceTable(attendanceList);
        // 获取全勤标兵
        List<UserAttendance> topUsers = getTopAttendanceUsers(attendanceList);
        // 构建表彰内容
        String praiseContent = buildPraiseSection(topUsers);
        // 生成完整公告
        String noticeContent = assembleNotice(lastMonth, tableContent, praiseContent);
        // 保存公告
        saveNotice(noticeContent);
    }

    /**
     * 构建考勤统计表格（Markdown格式表格，带正确换行）
     */
    private String buildAttendanceTable(List<UserAttendance> dataList) {
        StringBuilder tableBuilder = new StringBuilder();
        tableBuilder.append("| 部门         | 姓名                | 正常打卡天数 |\n")
                    .append("|---------------|---------------------|--------------------|\n");
        dataList.forEach(data ->
                tableBuilder.append(String.format("| %-5s | %-8s | %d        |\n",
                        data.getDeptName(), data.getUserName(), data.getNormalDays()))
        );
        return tableBuilder.toString();
    }

    /**
     * 获取全勤标兵（最高打卡天数用户）
     */
    private List<UserAttendance> getTopAttendanceUsers(List<UserAttendance> dataList) {
        if (dataList.isEmpty()) return Collections.emptyList();
        int maxDays = dataList.stream().mapToInt(UserAttendance::getNormalDays).max().orElse(0);
        return dataList.stream()
                .filter(user -> user.getNormalDays() == maxDays)
                .sorted(Comparator.comparing(UserAttendance::getDeptName))
                .collect(Collectors.toList());
    }

    /**
     * 构建表彰内容（添加段落间隔和换行）
     */
    private String buildPraiseSection(List<UserAttendance> topUsers) {
        if (topUsers.isEmpty()) {
            return "本月暂无全勤标兵，期待大家下月突破！\n\n" +
                    "希望全体员工向榜样看齐，严格遵守考勤制度，共同营造良好的工作氛围！";
        }

        String userList = topUsers.stream()
                .map(user -> String.format("%s（%s）", user.getUserName(), user.getDeptName()))
                .collect(Collectors.joining("、"));
        int maxDays = topUsers.get(0).getNormalDays();

        String prefix = topUsers.size() == 1 ? "恭喜" : "恭喜以下同事";
        String suffix = topUsers.size() == 1 ? "荣获" : "并列荣获";

        return String.format("%s %s 以 %d 天全勤的优异表现，%s本月「全勤标兵」称号！\n\n" +
                        "你们的坚持和自律是团队的榜样，希望继续保持高效的执行力，带动更多同事共同进步！",
                prefix, userList, maxDays, suffix);
    }

    /**
     * 组装完整公告内容（添加段落间隔和换行符）
     */
    private String assembleNotice(String lastMonth, String tableContent, String praiseContent) {
        return String.format("🌟 月度全勤标兵表彰（%s）\n\n" +  // 标题后换行
                        "### 一、考勤统计\n\n" +  // 章节标题后换行
                        "%s\n\n" +  // 表格前后换行
                        "### 二、全勤标兵表彰\n\n" +  // 章节标题后换行
                        "%s\n\n" +  // 表彰内容前后换行
                        "—— 人力资源部 & 考勤系统\n" +
                        "%s",  // 结尾日期前不换行
                lastMonth, tableContent, praiseContent,
                LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy年MM月dd日")));
    }

    /**
     * 通过部门ID获取部门名称
     */
    private String getDeptName(Long deptId) {
        if (deptId == null) return "未知部门";
        SysDept sysDept = sysDeptService.selectDeptById(deptId);
        return sysDept != null ? sysDept.getDeptName() : "未知部门";
    }

    /**
     * 保存公告到数据库
     */
    private void saveNotice(String content) {
        SysNotices notice = new SysNotices();
        notice.setNoticeTitle("【月度全勤表彰】" + LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy年MM月")));
        notice.setNoticeType("2"); // 公告类型（根据实际需求调整）
        notice.setNoticeContent(content);
        notice.setStatus("0"); // 正常状态
        notice.setCreateBy("system");
        notice.setCreateTime(new Date());

        sysNoticesService.insertSysNotices(notice);
        logger.info("月度全勤公告已生成，标题：{}", notice.getNoticeTitle());
    }

    /**
     * 用户考勤数据内部类（封装部门、姓名、打卡天数）
     */
    private static class UserAttendance {
        private final String deptName;
        private final String userName;
        private final int normalDays;

        public UserAttendance(String deptName, String userName, int normalDays) {
            this.deptName = deptName;
            this.userName = userName;
            this.normalDays = normalDays;
        }

        public String getDeptName() { return deptName; }
        public String getUserName() { return userName; }
        public int getNormalDays() { return normalDays; }
    }
}